#!/bin/bash
set -uo pipefail  # 不使用 -e，避免某一步出错直接退出整个流程

ENV_FILE="$HOME/.docker_env.sh"
if [[ ! -f "$ENV_FILE" ]]; then
  echo "[ERROR] Environment file not found: $ENV_FILE"
  exit 1
fi

echo "[INFO] Loading environment variables from $ENV_FILE"
# shellcheck source=/dev/null
source "$ENV_FILE"

: "${DOCKER_PASSWORD:?Environment variable DOCKER_PASSWORD not set}"
: "${HARBOR_DOMAIN:?Environment variable HARBOR_DOMAIN not set}"

# 默认命名空间（可通过 .env 中配置）
HARBOR_NAMESPACE="${HARBOR_NAMESPACE:-my-mirror}"

if [[ -n "${IMAGE_LIST_PATH:-}" ]]; then
  if [[ ! -f "$IMAGE_LIST_PATH" ]]; then
    echo "[ERROR] Local image list file not found: $IMAGE_LIST_PATH"
    exit 1
  fi
  IMAGE_LIST_FILE="$IMAGE_LIST_PATH"
elif [[ -n "${IMAGE_LIST_URL:-}" ]]; then
  IMAGE_LIST_FILE="/tmp/images.txt"
  echo "[INFO] Downloading image list from: $IMAGE_LIST_URL"
  curl -fsSL "$IMAGE_LIST_URL" -o "$IMAGE_LIST_FILE"
else
  echo "[ERROR] IMAGE_LIST_PATH or IMAGE_LIST_URL must be set."
  exit 1
fi

echo "[INFO] Logging into Harbor..."
echo "$DOCKER_PASSWORD" | sudo docker login --username 'robot$proxy_update' --password-stdin "$HARBOR_DOMAIN"

HARBOR_USER='robot$proxy_update'
HARBOR_PASS="$DOCKER_PASSWORD"

# 获取 digest
get_digest() {
  local image="$1"
  skopeo inspect --creds "$HARBOR_USER:$HARBOR_PASS" "docker://${image}" 2>/dev/null | jq -r '.Digest // empty' || true
}

get_src_digest() {
  local image="$1"
  skopeo inspect "docker://${image}" 2>/dev/null | jq -r '.Digest // empty' || true
}

# 构造目标 Harbor 镜像名
build_harbor_image() {
  local image="$1"
  echo "$HARBOR_DOMAIN/$HARBOR_NAMESPACE/$image"
}

# 推送逻辑
push_to_harbor() {
  local raw_image="$1"
  local src_image="$raw_image"
  local harbor_image
  harbor_image=$(build_harbor_image "$src_image")

  echo "[INFO] Checking digests for $src_image and $harbor_image ..."

  local src_digest
  local harbor_digest
  src_digest=$(get_src_digest "$src_image")
  harbor_digest=$(get_digest "$harbor_image")

  echo "[DEBUG] Source Digest: $src_digest"
  echo "[DEBUG] Harbor Digest: $harbor_digest"

  if [[ -z "$src_digest" ]]; then
    echo "[WARN] ❌ Could not fetch digest for source image: $src_image"
    return
  fi

  if [[ "$src_digest" == "$harbor_digest" ]]; then
    echo "[INFO] ✅ Already up-to-date, skipping: $src_image"
    return
  fi

  echo "[INFO] 🔄 Syncing image: $src_image"
  if ! sudo docker pull "$src_image"; then
    echo "[ERROR] ❌ Failed to pull $src_image"
    return
  fi

  sudo docker tag "$src_image" "$harbor_image"
  if ! sudo docker push "$harbor_image"; then
    echo "[ERROR] ❌ Failed to push $harbor_image"
    return
  fi

  echo "[INFO] ✅ Synced image: $harbor_image"
}

clean_unused_images() {
  echo "[INFO] Cleaning unused Docker images..."
  sudo docker image prune -a -f
}

# === 镜像批处理逻辑 ===
batch=()
batch_index=1
while IFS= read -r line || [[ -n "$line" ]]; do
  line=$(echo "$line" | sed 's/#.*//' | xargs)
  [[ -z "$line" ]] && continue

  if [[ "$line" == "###" ]]; then
    if [[ ${#batch[@]} -gt 0 ]]; then
      echo "[INFO] === Starting Batch $batch_index ==="
      for img in "${batch[@]}"; do
        push_to_harbor "$img" || echo "[WARN] Skipped $img due to error."
      done
      clean_unused_images
      batch=()
      ((batch_index++))
    fi
  else
    batch+=("$line")
  fi
done < "$IMAGE_LIST_FILE"

# 处理最后一个 batch
if [[ ${#batch[@]} -gt 0 ]]; then
  echo "[INFO] === Starting Final Batch $batch_index ==="
  for img in "${batch[@]}"; do
    push_to_harbor "$img" || echo "[WARN] Skipped $img due to error."
  done
  clean_unused_images
fi

echo "[INFO] ✅ All batches completed successfully."

